package com.example.demo0918_websocket.socket;

import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/api/ws/{sid}")
@Slf4j
public class SocketServer {
    private String sid;
    private static final ConcurrentHashMap<String, Session> SESSION_MAP = new ConcurrentHashMap<>();

    //连接成功
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid){
        this.sid = sid;
        SESSION_MAP.put(sid,session);
        log.info("有新连接：sid:{}，session:{},当前连接数：{}",sid,session.getId(),SESSION_MAP.size());
    }

    //连接关闭
    @OnClose
    public void onClose(Session session){
        SESSION_MAP.remove(this.sid);
        log.info("连接关闭：sid:{}，sessionId:{},当前连接数：{}",this.sid,session.getId(),SESSION_MAP.size());
    }

    //连接异常
    @OnError
    public void onError(Session session,Throwable error){
        log.error("{} 发生错误",session.getId(),error);
    }

    //收到消息
    @OnMessage
    public void onMessage(String msg,Session session){
        log.info("收到消息：{}，内容：{}",sid,msg);
        if ("ping".equals(msg)){
            try {
                session.getBasicRemote().sendText("pong");
            } catch (IOException e) {
                log.error("推送消息失败：{}，内容：{}",sid,msg);
            }
        }else {
//            sendMeasureDataInfo(msg);
            sendMeasureDataInfoExcludeSelf(msg,sid);
        }
    }

    //群发消息
    public void sendMeasureDataInfo(String msg){
        for (String sid : SESSION_MAP.keySet()) {
            Session session = SESSION_MAP.get(sid);
            try {
                session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                log.error("推送消息失败：{}，内容：{}",sid,msg);
            }
            log.info("推送消息：{}，内容：{}",sid,msg);
        }
    }

    //群发消息，排除发消息的人
    private void sendMeasureDataInfoExcludeSelf(String msg,String sidSelf){
        for (String sid : SESSION_MAP.keySet()) {
            if (sidSelf.equals(sid)){
                continue;
            }
            Session session = SESSION_MAP.get(sid);
            try {
                session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                log.error("推送消息失败：{}，内容：{}",sid,msg);
            }
            log.info("推送消息：{}，内容：{}",sid,msg);
        }
    }
}